/*----------------------------------------------------------------------------------------
*
*  Copyright 2019, Gao Hai Hui, <fromzeropoint@126.com>.  All rights reserved.
*  https://gitee.com/helloworldghh/xoskit.git
*  Use of this source code is governed by a MIT license
*  that can be found in the License file.
*
----------------------------------------------------------------------------------------*/
#ifndef __18850E12_BDCF_495a_82DA_6C1934107DA5__
#define __18850E12_BDCF_495a_82DA_6C1934107DA5__

#include "../macro/head.h"
#include "../release/head.h"

/////////////////////////////////////////////////////////////////////////////////////////
// 
namespace xos
{
    // 
    // tcp interface
    // 
    class i_socket : public i_release
    {
    public:
        enum enumShutdown
        {
            XOS_SD_RECEIVE = 0x01,
            XOS_SD_SEND = 0x02,
            XOS_SD_BOTH = XOS_SD_RECEIVE | XOS_SD_SEND
        };

    protected:
        virtual ~i_socket(){}

    public:
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // 

        // 
        // udp端口初始化
        // 
        virtual int udp_init( const char * lpszLocalIp, uint16_t usLocalPort ) = 0;

        // 
        // 返回值，为发送的字节数, -1表示失败
        // 
        virtual int udp_send( const char * lpBuf, int nLen, const char * lpszToIp, uint16_t usToPort ) = 0;

        // 
        // 返回值，为接收到的字节数, -1表示失败
        // 
        virtual int udp_recv( char * lpBuf, int nLen, char * lpszFromIp, uint16_t * lpusFromPort ) = 0;

        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // 

        // 
        // tcp服务端端口初始化
        // 
        virtual int tcp_init( const char * lpszLocalIp, uint16_t usLocalPort, bool bBind ) = 0;

        // 
        // accept
        // 
        virtual int tcp_accept( i_socket ** ppv ) = 0;

        // 
        // connect
        // 
        virtual int tcp_connect( const char * lpszServerIp, uint16_t usServerPort ) = 0;

        // 
        // tcp侦听
        // 
        virtual int tcp_listen( int nNum ) = 0;

        // 
        // 返回值，为发送的字节数, -1表示失败
        // 
        virtual int tcp_send( const char * lpBuf, int nLen ) = 0;

        // 
        // 返回值，为接收到的字节数, -1表示失败
        // 
        virtual int tcp_recv( char * lpBuf, int nLen ) = 0;

        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // 

        // fill addr
        virtual int fill_addr( uint16_t af, sockaddr_storage & ss_addr, const char * lpszIp, uint16_t uPort ) = 0;
        virtual int fill_addr( sockaddr_storage & ss_addr, const char * lpszIp, uint16_t uPort ) = 0;

        virtual int fill_ipv6( sockaddr_storage & ss_addr, const char * lpszIp, uint16_t uPort ) = 0;
        virtual int fill_ipv6_port( sockaddr_storage & ss_addr, uint16_t uPort ) = 0;
        virtual int fill_ipv6_ip( sockaddr_storage & ss_addr, const char * lpszIp ) = 0;

        virtual int fill_ipv4( sockaddr_storage & ss_addr, const char * lpszIp, uint16_t uPort ) = 0;
        virtual int fill_ipv4_port( sockaddr_storage & ss_addr, uint16_t uPort ) = 0;
        virtual int fill_ipv4_ip( sockaddr_storage & ss_addr, const char * lpszIp ) = 0;

        // ipv4 map ipv6
        virtual int ipv4_map_ipv6( char * lpszIpv6, int nSize, const char * lpszIpv4 ) = 0;
        virtual int get_ipv6_addr( sockaddr_storage & addr, const char * lpszIp ) = 0;
        virtual bool invalid_addr_name( const char * lpszName ) = 0;

        // 
        // 解析域名或机器名
        // 
        virtual int get_addr_by_name( const char * lpszName, sockaddr_storage * pIpv6Addr, sockaddr_storage * pIpv4Addr ) = 0;

        // 
        // 从地址得到IP和端口
        // 
        virtual int get_ip_port( sockaddr_storage & ss_addr, char * lpszIp, uint16_t * lpusPort ) = 0;

        // 
        // 根据socket句柄得到IP和端口
        // 
        virtual int get_local_addr( char * lpszIp, uint16_t * lpusPort ) = 0;
        virtual int get_peer_addr( char * lpszIp, uint16_t * lpusPort ) = 0;

        // 
        // 取得socket句柄
        // 
        virtual void set_socket( uint64_t ulSocket ) = 0;
        virtual uint64_t get_socket() = 0;

        // 
        // 设置异步/阻塞模式
        // 
        virtual int set_async( bool bAsync ) = 0;
        virtual int set_nodelay() = 0;

        // 
        // 停止后续发送
        // 
        virtual int shut_down( int how ) = 0;

        // 
        // 关闭端口
        // 
        virtual int close( int onoff, int linger ) = 0;

        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // 

        // 
        // 保存地址
        // 
        virtual void set_local_addr( sockaddr_storage & ss_addr ) = 0;
        virtual void set_peer_addr( sockaddr_storage & ss_addr ) = 0;
        virtual sockaddr_storage & get_local_addr() = 0;
        virtual sockaddr_storage & get_peer_addr() = 0;

        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // 

        // 
        // release
        // 
        virtual int init() = 0;
        virtual int term() = 0;
    };
}

#endif // __18850E12_BDCF_495a_82DA_6C1934107DA5__
